﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using HslCommunication.Core;
using HslCommunication.Reflection;

namespace HslCommunication.LogNet
{
	/// <summary>
	/// 日志存储类的基类，提供一些基础的服务
	/// </summary>
	/// <remarks>
	/// 基于此类可以实现任意的规则的日志存储规则，欢迎大家补充实现，本组件实现了3个日志类
	/// <list type="number">
	/// <item>单文件日志类 <see cref="T:HslCommunication.LogNet.LogNetSingle" /></item>
	/// <item>根据文件大小的类 <see cref="T:HslCommunication.LogNet.LogNetFileSize" /></item>
	/// <item>根据时间进行存储的类 <see cref="T:HslCommunication.LogNet.LogNetDateTime" /></item>
	/// </list>
	/// </remarks>
	// Token: 0x020000D6 RID: 214
	public abstract class LogNetBase : IDisposable
	{
		/// <summary>
		/// 实例化一个日志对象<br />
		/// Instantiate a log object
		/// </summary>
		// Token: 0x060010DC RID: 4316 RVA: 0x00060F48 File Offset: 0x0005F148
		public LogNetBase()
		{
			this.m_fileSaveLock = new SimpleHybirdLock();
			this.m_simpleHybirdLock = new SimpleHybirdLock();
			this.m_WaitForSave = new Queue<HslMessageItem>();
			this.filtrateKeyword = new List<string>();
			this.filtrateLock = new SimpleHybirdLock();
		}

		/// <inheritdoc cref="E:HslCommunication.LogNet.ILogNet.BeforeSaveToFile" />
		// Token: 0x1400001E RID: 30
		// (add) Token: 0x060010DD RID: 4317 RVA: 0x00060FB0 File Offset: 0x0005F1B0
		// (remove) Token: 0x060010DE RID: 4318 RVA: 0x00060FE8 File Offset: 0x0005F1E8
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event EventHandler<HslEventArgs> BeforeSaveToFile = null;

		// Token: 0x060010DF RID: 4319 RVA: 0x0006101D File Offset: 0x0005F21D
		private void OnBeforeSaveToFile(HslEventArgs args)
		{
			EventHandler<HslEventArgs> beforeSaveToFile = this.BeforeSaveToFile;
			if (beforeSaveToFile != null)
			{
				beforeSaveToFile(this, args);
			}
		}

		/// <inheritdoc cref="P:HslCommunication.LogNet.ILogNet.LogSaveMode" />
		// Token: 0x1700025B RID: 603
		// (get) Token: 0x060010E0 RID: 4320 RVA: 0x00061033 File Offset: 0x0005F233
		// (set) Token: 0x060010E1 RID: 4321 RVA: 0x0006103B File Offset: 0x0005F23B
		public LogSaveMode LogSaveMode { get; protected set; }

		/// <inheritdoc cref="P:HslCommunication.LogNet.ILogNet.LogNetStatistics" />
		// Token: 0x1700025C RID: 604
		// (get) Token: 0x060010E2 RID: 4322 RVA: 0x00061044 File Offset: 0x0005F244
		// (set) Token: 0x060010E3 RID: 4323 RVA: 0x0006104C File Offset: 0x0005F24C
		public LogStatistics LogNetStatistics { get; set; }

		/// <inheritdoc cref="P:HslCommunication.LogNet.ILogNet.ConsoleOutput" />
		// Token: 0x1700025D RID: 605
		// (get) Token: 0x060010E4 RID: 4324 RVA: 0x00061055 File Offset: 0x0005F255
		// (set) Token: 0x060010E5 RID: 4325 RVA: 0x0006105D File Offset: 0x0005F25D
		public bool ConsoleOutput { get; set; }

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteDebug(System.String)" />
		// Token: 0x060010E6 RID: 4326 RVA: 0x00061066 File Offset: 0x0005F266
		[HslMqttApi]
		public void WriteDebug(string text)
		{
			this.WriteDebug(string.Empty, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteDebug(System.String,System.String)" />
		// Token: 0x060010E7 RID: 4327 RVA: 0x00061075 File Offset: 0x0005F275
		[HslMqttApi(ApiTopic = "WriteDebugKeyWord")]
		public void WriteDebug(string keyWord, string text)
		{
			this.RecordMessage(HslMessageDegree.DEBUG, keyWord, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteInfo(System.String)" />
		// Token: 0x060010E8 RID: 4328 RVA: 0x00061081 File Offset: 0x0005F281
		[HslMqttApi]
		public void WriteInfo(string text)
		{
			this.WriteInfo(string.Empty, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteInfo(System.String,System.String)" />
		// Token: 0x060010E9 RID: 4329 RVA: 0x00061090 File Offset: 0x0005F290
		[HslMqttApi(ApiTopic = "WriteInfoKeyWord")]
		public void WriteInfo(string keyWord, string text)
		{
			this.RecordMessage(HslMessageDegree.INFO, keyWord, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteWarn(System.String)" />
		// Token: 0x060010EA RID: 4330 RVA: 0x0006109C File Offset: 0x0005F29C
		[HslMqttApi]
		public void WriteWarn(string text)
		{
			this.WriteWarn(string.Empty, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteWarn(System.String,System.String)" />
		// Token: 0x060010EB RID: 4331 RVA: 0x000610AB File Offset: 0x0005F2AB
		[HslMqttApi(ApiTopic = "WriteWarnKeyWord")]
		public void WriteWarn(string keyWord, string text)
		{
			this.RecordMessage(HslMessageDegree.WARN, keyWord, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteError(System.String)" />
		// Token: 0x060010EC RID: 4332 RVA: 0x000610B7 File Offset: 0x0005F2B7
		[HslMqttApi]
		public void WriteError(string text)
		{
			this.WriteError(string.Empty, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteError(System.String,System.String)" />
		// Token: 0x060010ED RID: 4333 RVA: 0x000610C6 File Offset: 0x0005F2C6
		[HslMqttApi(ApiTopic = "WriteErrorKeyWord")]
		public void WriteError(string keyWord, string text)
		{
			this.RecordMessage(HslMessageDegree.ERROR, keyWord, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteFatal(System.String)" />
		// Token: 0x060010EE RID: 4334 RVA: 0x000610D2 File Offset: 0x0005F2D2
		[HslMqttApi]
		public void WriteFatal(string text)
		{
			this.WriteFatal(string.Empty, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteFatal(System.String,System.String)" />
		// Token: 0x060010EF RID: 4335 RVA: 0x000610E1 File Offset: 0x0005F2E1
		[HslMqttApi(ApiTopic = "WriteFatalKeyWord")]
		public void WriteFatal(string keyWord, string text)
		{
			this.RecordMessage(HslMessageDegree.FATAL, keyWord, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteException(System.String,System.Exception)" />
		// Token: 0x060010F0 RID: 4336 RVA: 0x000610ED File Offset: 0x0005F2ED
		public void WriteException(string keyWord, Exception ex)
		{
			this.WriteException(keyWord, string.Empty, ex);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteException(System.String,System.String,System.Exception)" />
		// Token: 0x060010F1 RID: 4337 RVA: 0x000610FD File Offset: 0x0005F2FD
		public void WriteException(string keyWord, string text, Exception ex)
		{
			this.RecordMessage(HslMessageDegree.FATAL, keyWord, LogNetManagment.GetSaveStringFromException(text, ex));
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.RecordMessage(HslCommunication.LogNet.HslMessageDegree,System.String,System.String)" />
		// Token: 0x060010F2 RID: 4338 RVA: 0x0006110F File Offset: 0x0005F30F
		public void RecordMessage(HslMessageDegree degree, string keyWord, string text)
		{
			this.WriteToFile(degree, keyWord, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteDescrition(System.String)" />
		// Token: 0x060010F3 RID: 4339 RVA: 0x0006111C File Offset: 0x0005F31C
		[HslMqttApi]
		public void WriteDescrition(string description)
		{
			bool flag = string.IsNullOrEmpty(description);
			if (!flag)
			{
				StringBuilder stringBuilder = new StringBuilder("\u0002");
				stringBuilder.Append(Environment.NewLine);
				stringBuilder.Append("\u0002/");
				int num = 118 - this.CalculateStringOccupyLength(description);
				bool flag2 = num >= 8;
				if (flag2)
				{
					int num2 = (num - 8) / 2;
					this.AppendCharToStringBuilder(stringBuilder, '*', num2);
					stringBuilder.Append("   ");
					stringBuilder.Append(description);
					stringBuilder.Append("   ");
					bool flag3 = num % 2 == 0;
					if (flag3)
					{
						this.AppendCharToStringBuilder(stringBuilder, '*', num2);
					}
					else
					{
						this.AppendCharToStringBuilder(stringBuilder, '*', num2 + 1);
					}
				}
				else
				{
					bool flag4 = num >= 2;
					if (flag4)
					{
						int num3 = (num - 2) / 2;
						this.AppendCharToStringBuilder(stringBuilder, '*', num3);
						stringBuilder.Append(description);
						bool flag5 = num % 2 == 0;
						if (flag5)
						{
							this.AppendCharToStringBuilder(stringBuilder, '*', num3);
						}
						else
						{
							this.AppendCharToStringBuilder(stringBuilder, '*', num3 + 1);
						}
					}
					else
					{
						stringBuilder.Append(description);
					}
				}
				stringBuilder.Append("/");
				stringBuilder.Append(Environment.NewLine);
				this.RecordMessage(HslMessageDegree.None, string.Empty, stringBuilder.ToString());
			}
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteAnyString(System.String)" />
		// Token: 0x060010F4 RID: 4340 RVA: 0x00061262 File Offset: 0x0005F462
		[HslMqttApi]
		public void WriteAnyString(string text)
		{
			this.RecordMessage(HslMessageDegree.None, string.Empty, text);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.WriteNewLine" />
		// Token: 0x060010F5 RID: 4341 RVA: 0x00061272 File Offset: 0x0005F472
		[HslMqttApi]
		public void WriteNewLine()
		{
			this.RecordMessage(HslMessageDegree.None, string.Empty, "\u0002" + Environment.NewLine);
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.SetMessageDegree(HslCommunication.LogNet.HslMessageDegree)" />
		// Token: 0x060010F6 RID: 4342 RVA: 0x00061290 File Offset: 0x0005F490
		public void SetMessageDegree(HslMessageDegree degree)
		{
			this.m_messageDegree = degree;
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.FiltrateKeyword(System.String)" />
		// Token: 0x060010F7 RID: 4343 RVA: 0x0006129C File Offset: 0x0005F49C
		[HslMqttApi]
		public void FiltrateKeyword(string keyword)
		{
			this.filtrateLock.Enter();
			bool flag = !this.filtrateKeyword.Contains(keyword);
			if (flag)
			{
				this.filtrateKeyword.Add(keyword);
			}
			this.filtrateLock.Leave();
		}

		/// <inheritdoc cref="M:HslCommunication.LogNet.ILogNet.RemoveFiltrate(System.String)" />
		// Token: 0x060010F8 RID: 4344 RVA: 0x000612E4 File Offset: 0x0005F4E4
		[HslMqttApi]
		public void RemoveFiltrate(string keyword)
		{
			this.filtrateLock.Enter();
			bool flag = this.filtrateKeyword.Contains(keyword);
			if (flag)
			{
				this.filtrateKeyword.Remove(keyword);
			}
			this.filtrateLock.Leave();
		}

		// Token: 0x060010F9 RID: 4345 RVA: 0x0006132C File Offset: 0x0005F52C
		private void WriteToFile(HslMessageDegree degree, string keyword, string text)
		{
			bool flag = degree <= this.m_messageDegree;
			if (flag)
			{
				HslMessageItem hslMessageItem = this.GetHslMessageItem(degree, keyword, text);
				this.AddItemToCache(hslMessageItem);
			}
		}

		// Token: 0x060010FA RID: 4346 RVA: 0x0006135E File Offset: 0x0005F55E
		private void AddItemToCache(HslMessageItem item)
		{
			this.m_simpleHybirdLock.Enter();
			this.m_WaitForSave.Enqueue(item);
			this.m_simpleHybirdLock.Leave();
			this.StartSaveFile();
		}

		// Token: 0x060010FB RID: 4347 RVA: 0x00061390 File Offset: 0x0005F590
		private void StartSaveFile()
		{
			bool flag = Interlocked.CompareExchange(ref this.m_SaveStatus, 1, 0) == 0;
			if (flag)
			{
				ThreadPool.QueueUserWorkItem(new WaitCallback(this.ThreadPoolSaveFile), null);
			}
		}

		// Token: 0x060010FC RID: 4348 RVA: 0x000613C8 File Offset: 0x0005F5C8
		private HslMessageItem GetAndRemoveLogItem()
		{
			this.m_simpleHybirdLock.Enter();
			HslMessageItem result = (this.m_WaitForSave.Count > 0) ? this.m_WaitForSave.Dequeue() : null;
			this.m_simpleHybirdLock.Leave();
			return result;
		}

		// Token: 0x060010FD RID: 4349 RVA: 0x00061414 File Offset: 0x0005F614
		private void ConsoleWriteLog(HslMessageItem log)
		{
			bool flag = log.Degree == HslMessageDegree.DEBUG;
			if (flag)
			{
				Console.ForegroundColor = ConsoleColor.DarkGray;
			}
			else
			{
				bool flag2 = log.Degree == HslMessageDegree.INFO;
				if (flag2)
				{
					Console.ForegroundColor = ConsoleColor.White;
				}
				else
				{
					bool flag3 = log.Degree == HslMessageDegree.WARN;
					if (flag3)
					{
						Console.ForegroundColor = ConsoleColor.Yellow;
					}
					else
					{
						bool flag4 = log.Degree == HslMessageDegree.ERROR;
						if (flag4)
						{
							Console.ForegroundColor = ConsoleColor.Red;
						}
						else
						{
							bool flag5 = log.Degree == HslMessageDegree.FATAL;
							if (flag5)
							{
								Console.ForegroundColor = ConsoleColor.DarkRed;
							}
							else
							{
								Console.ForegroundColor = ConsoleColor.White;
							}
						}
					}
				}
			}
			Console.WriteLine(log.ToString());
		}

		// Token: 0x060010FE RID: 4350 RVA: 0x000614AC File Offset: 0x0005F6AC
		private void ThreadPoolSaveFile(object obj)
		{
			HslMessageItem andRemoveLogItem = this.GetAndRemoveLogItem();
			this.m_fileSaveLock.Enter();
			string fileSaveName = this.GetFileSaveName();
			bool flag = !string.IsNullOrEmpty(fileSaveName);
			if (flag)
			{
				StreamWriter streamWriter = null;
				try
				{
					streamWriter = new StreamWriter(fileSaveName, true, Encoding.UTF8);
					while (andRemoveLogItem != null)
					{
						bool consoleOutput = this.ConsoleOutput;
						if (consoleOutput)
						{
							this.ConsoleWriteLog(andRemoveLogItem);
						}
						this.OnBeforeSaveToFile(new HslEventArgs
						{
							HslMessage = andRemoveLogItem
						});
						LogStatistics logNetStatistics = this.LogNetStatistics;
						if (logNetStatistics != null)
						{
							logNetStatistics.StatisticsAdd(1L);
						}
						this.filtrateLock.Enter();
						bool flag2 = !this.filtrateKeyword.Contains(andRemoveLogItem.KeyWord);
						this.filtrateLock.Leave();
						bool cancel = andRemoveLogItem.Cancel;
						if (cancel)
						{
							flag2 = false;
						}
						bool flag3 = flag2;
						if (flag3)
						{
							streamWriter.Write(this.HslMessageFormate(andRemoveLogItem));
							streamWriter.Write(Environment.NewLine);
							streamWriter.Flush();
						}
						andRemoveLogItem = this.GetAndRemoveLogItem();
					}
				}
				catch (Exception ex)
				{
					this.AddItemToCache(andRemoveLogItem);
					this.AddItemToCache(new HslMessageItem
					{
						Degree = HslMessageDegree.FATAL,
						Text = LogNetManagment.GetSaveStringFromException("LogNetSelf", ex)
					});
				}
				finally
				{
					if (streamWriter != null)
					{
						streamWriter.Dispose();
					}
				}
			}
			else
			{
				while (andRemoveLogItem != null)
				{
					bool consoleOutput2 = this.ConsoleOutput;
					if (consoleOutput2)
					{
						this.ConsoleWriteLog(andRemoveLogItem);
					}
					this.OnBeforeSaveToFile(new HslEventArgs
					{
						HslMessage = andRemoveLogItem
					});
					andRemoveLogItem = this.GetAndRemoveLogItem();
				}
			}
			this.m_fileSaveLock.Leave();
			Interlocked.Exchange(ref this.m_SaveStatus, 0);
			this.OnWriteCompleted();
			bool flag4 = this.m_WaitForSave.Count > 0;
			if (flag4)
			{
				this.StartSaveFile();
			}
		}

		// Token: 0x060010FF RID: 4351 RVA: 0x000616B4 File Offset: 0x0005F8B4
		private string HslMessageFormate(HslMessageItem hslMessage)
		{
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = hslMessage.Degree != HslMessageDegree.None;
			if (flag)
			{
				stringBuilder.Append("\u0002");
				stringBuilder.Append("[");
				stringBuilder.Append(LogNetManagment.GetDegreeDescription(hslMessage.Degree));
				stringBuilder.Append("] ");
				stringBuilder.Append(hslMessage.Time.ToString("yyyy-MM-dd HH:mm:ss.fff"));
				stringBuilder.Append(" thread:[");
				stringBuilder.Append(hslMessage.ThreadId.ToString("D3"));
				stringBuilder.Append("] ");
				bool flag2 = !string.IsNullOrEmpty(hslMessage.KeyWord);
				if (flag2)
				{
					stringBuilder.Append(hslMessage.KeyWord);
					stringBuilder.Append(" : ");
				}
			}
			stringBuilder.Append(hslMessage.Text);
			return stringBuilder.ToString();
		}

		/// <inheritdoc />
		// Token: 0x06001100 RID: 4352 RVA: 0x000617A7 File Offset: 0x0005F9A7
		public override string ToString()
		{
			return string.Format("LogNetBase[{0}]", this.LogSaveMode);
		}

		/// <inheritdoc />
		// Token: 0x06001101 RID: 4353 RVA: 0x000617BE File Offset: 0x0005F9BE
		protected virtual string GetFileSaveName()
		{
			return string.Empty;
		}

		/// <summary>
		/// 当写入文件完成的时候触发，这时候已经释放了文件的句柄了。<br />
		/// Triggered when writing to the file is complete, and the file handle has been released.
		/// </summary>
		// Token: 0x06001102 RID: 4354 RVA: 0x00009AA1 File Offset: 0x00007CA1
		protected virtual void OnWriteCompleted()
		{
		}

		// Token: 0x06001103 RID: 4355 RVA: 0x000617C8 File Offset: 0x0005F9C8
		private HslMessageItem GetHslMessageItem(HslMessageDegree degree, string keyWord, string text)
		{
			return new HslMessageItem
			{
				KeyWord = keyWord,
				Degree = degree,
				Text = text,
				ThreadId = Thread.CurrentThread.ManagedThreadId
			};
		}

		// Token: 0x06001104 RID: 4356 RVA: 0x00061808 File Offset: 0x0005FA08
		private int CalculateStringOccupyLength(string str)
		{
			bool flag = string.IsNullOrEmpty(str);
			int result;
			if (flag)
			{
				result = 0;
			}
			else
			{
				int num = 0;
				for (int i = 0; i < str.Length; i++)
				{
					bool flag2 = str[i] >= '一' && str[i] <= '龻';
					if (flag2)
					{
						num += 2;
					}
					else
					{
						num++;
					}
				}
				result = num;
			}
			return result;
		}

		// Token: 0x06001105 RID: 4357 RVA: 0x0006187C File Offset: 0x0005FA7C
		private void AppendCharToStringBuilder(StringBuilder sb, char c, int count)
		{
			for (int i = 0; i < count; i++)
			{
				sb.Append(c);
			}
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		/// <param name="disposing">是否初次调用</param>
		// Token: 0x06001106 RID: 4358 RVA: 0x000618A4 File Offset: 0x0005FAA4
		protected virtual void Dispose(bool disposing)
		{
			bool flag = !this.disposedValue;
			if (flag)
			{
				if (disposing)
				{
					this.m_simpleHybirdLock.Dispose();
					this.m_WaitForSave.Clear();
					this.m_fileSaveLock.Dispose();
				}
				this.disposedValue = true;
			}
		}

		/// <inheritdoc cref="M:System.IDisposable.Dispose" />
		// Token: 0x06001107 RID: 4359 RVA: 0x000618F3 File Offset: 0x0005FAF3
		public void Dispose()
		{
			this.Dispose(true);
		}

		/// <summary>
		/// 文件存储的锁
		/// </summary>
		// Token: 0x0400044C RID: 1100
		protected SimpleHybirdLock m_fileSaveLock;

		// Token: 0x0400044D RID: 1101
		private HslMessageDegree m_messageDegree = HslMessageDegree.DEBUG;

		// Token: 0x0400044E RID: 1102
		private Queue<HslMessageItem> m_WaitForSave;

		// Token: 0x0400044F RID: 1103
		private SimpleHybirdLock m_simpleHybirdLock;

		// Token: 0x04000450 RID: 1104
		private int m_SaveStatus = 0;

		// Token: 0x04000451 RID: 1105
		private List<string> filtrateKeyword;

		// Token: 0x04000452 RID: 1106
		private SimpleHybirdLock filtrateLock;

		// Token: 0x04000457 RID: 1111
		private bool disposedValue = false;
	}
}
